#ifndef FKFILEINFO_H
#define FKFILEINFO_H

#include <QString>
#include <QList>
#include <QDir>
#include <QFileInfo>
#include "FKPaths.h"
#include "FKOSType.h"
#include "FKCompilerTypes.h"
#include "FKLogger.h"

struct FKFileInfo{
    FKFileInfo():name(QString()),fileName(QString()),relativePath(QString()),version(QString()),size(0),fileType(other),OStype(0){}
    FKFileInfo(const FKFileInfo &other):
        name(other.name),
        fileName(other.fileName),
        relativePath(other.relativePath),
        version(other.version),
        size(other.size),
        fileType(other.fileType),
        OStype(other.OStype){}
    QString name;
    QString fileName;
    QString relativePath;
    QString version;
    qint64 size;
    enum FileType{executable,library,other};
    FileType fileType;
    quint8 OStype;
    static FKFileInfo makeLibrarySet(const QString &name, QString version);
    static FKFileInfo makeExecutionSet(const QString &name, QString version);
    static FKFileInfo makePlatformSet(const QString &name, QString version);
    static QList<FKFileInfo> makeDirectorySet(const QString &appPath, const QString &relativePath, const QString &name, QString version);
private:
    static FKFileInfo makeFolderedSet(const QString &relativePath, const QString &fName, const QString &name, QString version);
};

inline FKFileInfo FKFileInfo::makeLibrarySet(const QString &name, QString version){
    FKFileInfo f;
    const FKFileInfo::FileType ft=FKFileInfo::library;
    version+=FKCompilerTypes::current;

#ifdef Q_OS_WIN32
    f.name=name;
    f.fileName=name+QString(".dll");
    f.version=version;
    f.fileType=ft;
    f.relativePath=FKPaths::binSubfolderWin;
    f.OStype=FKOSType::winOS;
#else
#ifdef Q_OS_MAC
    f.name=name;
    f.fileName=QString("lib")+name+QString(".dylib");
    f.version=version;
    f.fileType=ft;
    f.relativePath=FKPaths::binSubfolderMac;
    f.OStype=FKOSType::macOS;
#else
    f.name=name;
    f.fileName=name+QString(".so");
    f.version=version;
    f.fileType=ft;
    f.relativePath=FKPaths::binSubfolderNix;
    f.OStype=FKOSType::nixOS;
#endif
#endif

    return f;
}

inline FKFileInfo FKFileInfo::makeExecutionSet(const QString &name, QString version){
    FKFileInfo f;
    const FKFileInfo::FileType ft=FKFileInfo::executable;
    version+=FKCompilerTypes::current;

#ifdef Q_OS_WIN32
    f.name=name;
    f.fileName=name+QString(".exe");
    f.version=version;
    f.fileType=ft;
    f.relativePath=FKPaths::binSubfolderWin;
    f.OStype=FKOSType::winOS;
#else
#ifdef Q_OS_MAC
    f.name=name;
    f.fileName=name;
    f.version=version;
    f.fileType=ft;
    f.relativePath=FKPaths::binSubfolderMac;
    f.OStype=FKOSType::macOS;
#else
    f.name=name;
    f.fileName=name;
    f.version=version;
    f.fileType=ft;
    f.relativePath=FKPaths::binSubfolderNix;
    f.OStype=FKOSType::nixOS;
#endif
#endif

    return f;
}

inline FKFileInfo FKFileInfo::makePlatformSet(const QString &name, QString version){
    FKFileInfo f;
    const FKFileInfo::FileType ft=FKFileInfo::other;
    version+=FKCompilerTypes::current;

#ifdef Q_OS_WIN32
    f.name=name;
    f.fileName=name;
    f.version=version;
    f.fileType=ft;
    f.relativePath=FKPaths::binSubfolderWin;
    f.OStype=FKOSType::winOS;
#else
#ifdef Q_OS_MAC
    f.name=name;
    f.fileName=name;
    f.version=version;
    f.fileType=ft;
    f.relativePath=FKPaths::binSubfolderMac;
    f.OStype=FKOSType::macOS;
#else
    f.name=name;
    f.fileName=name;
    f.version=version;
    f.fileType=ft;
    f.relativePath=FKPaths::binSubfolderNix;
    f.OStype=FKOSType::nixOS;
#endif
#endif

    return f;
}

inline QList<FKFileInfo> FKFileInfo::makeDirectorySet(const QString &appPath, const QString &relativePath, const QString &name, QString version){
    QList<FKFileInfo> lst;
    QDir d(appPath+"/"+relativePath);
//    FK_MLOGV("dir exist",d.AllEntries)
    QFileInfoList fi=d.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
    foreach (QFileInfo f, fi) {
        if(f.isFile()){
            lst.append(makeFolderedSet(relativePath,f.fileName(),name+"/"+f.fileName(),version));
        }else{
            lst.append(makeDirectorySet(appPath,relativePath+f.fileName()+"/",name+"/"+f.fileName(),version));
        }
    }
    return lst;
}

inline FKFileInfo FKFileInfo::makeFolderedSet(const QString &relativePath, const QString &fName, const QString &name, QString version){
    FKFileInfo f;
    const FKFileInfo::FileType ft=FKFileInfo::other;
//    version+=FKCompilerTypes::current;

    f.name=name;
    f.fileName=fName;
    f.version=version;
    f.fileType=ft;
    f.relativePath="../bin_win/"+relativePath;
    f.OStype=FKOSType::winOS;

    return f;
}

#endif // FKFILEINFO_H
